#include "main.h"
#include "lcd.h"
#include "font.h"


/**
 *  @brief  i2c的延时函数，延时时间要 > 4us
 *  @param  无
 *  @retval 无
 *  @note   可用逻辑分析仪测量I2C通讯时的频率工作条件
 */
static void i2c_delay( void )
{
    int i;

    for ( i = 0; i < 10; i++ )
    {
        asm( "nop" );  // 空语句
    }
}


/**
 *  @brief  i2c SCL 拉高
 *  @param  无
 *  @retval 无
 */
static void i2c_scl_high( void )
{
    HAL_GPIO_WritePin( SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET );
}


/**
 *  @brief  i2c SCL 拉低
 *  @param  无
 *  @retval 无
 */
static void i2c_scl_low( void )
{
    HAL_GPIO_WritePin( SCL_GPIO_Port, SCL_Pin, GPIO_PIN_RESET );
}


static void Soft_IIC_Output( void )
{
    GPIO_InitTypeDef SOFT_IIC_GPIO_STRUCT;
    SOFT_IIC_GPIO_STRUCT.Mode = GPIO_MODE_OUTPUT_PP;
    SOFT_IIC_GPIO_STRUCT.Pin = SDA_Pin;
    SOFT_IIC_GPIO_STRUCT.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init( SDA_GPIO_Port, &SOFT_IIC_GPIO_STRUCT );
}

/**
 * @brief SDA引脚设置输入模式
 * @param  无
 * @return 无
 */
static void Soft_IIC_Input( void )
{
    GPIO_InitTypeDef SOFT_IIC_GPIO_STRUCT;
    SOFT_IIC_GPIO_STRUCT.Mode = GPIO_MODE_INPUT;
    SOFT_IIC_GPIO_STRUCT.Pin = SDA_Pin;
    SOFT_IIC_GPIO_STRUCT.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init( SDA_GPIO_Port, &SOFT_IIC_GPIO_STRUCT );
}

/**
 *  @brief  i2c SDA 拉高
 *  @param  无
 *  @retval 无
 */
static void i2c_sda_high( void )
{
    HAL_GPIO_WritePin( SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET );
}


/**
 *  @brief  i2c SDA 拉低
 *  @param  无
 *  @retval 无
 */
static void i2c_sda_low( void )
{
    HAL_GPIO_WritePin( SDA_GPIO_Port, SDA_Pin, GPIO_PIN_RESET );
}


/**
 *  @brief  读取SDA线上的值
 *  @param  无
 *  @retval 读取到的值，0或1
 */
static uint8_t i2c_read_sda_value( void )
{
    return HAL_GPIO_ReadPin( SDA_GPIO_Port, SDA_Pin );;
}


/**
 *  @brief  i2c的起始信号
 *  @param  无
 *  @retval 无
 */
static void i2c_start( void )
{
    Soft_IIC_Output();
    /* 当SCL高电平时，SDA出现一个下跳沿表示I2C总线启动信号 */
    i2c_scl_high();
    i2c_sda_high();
    i2c_delay();

    i2c_sda_low();
    i2c_delay();

    i2c_scl_low();
    i2c_delay();
}


/**
 *  @brief  i2c的停止信号
 *  @param  无
 *  @retval 无
 */
static void i2c_stop( void )
{
    Soft_IIC_Output();
    /* 当SCL高电平时，SDA出现一个上跳沿表示I2C总线停止信号 */
    i2c_sda_low();
    i2c_scl_high();
    i2c_delay();

    i2c_sda_high();
}


/**
 *  @brief  i2c 发送一个字节
 *  @param  要发送的数据
 *  @retval 无
 */
void i2c_write_byte( uint8_t data )
{
    uint8_t i;

    i2c_scl_low();
    i2c_delay();

    /* 先发送字节的高位 bit7 */
    for ( i = 0; i < 8; i++ )
    {
        if ( data & 0x80 )
        {
            i2c_sda_high();
        }
        else
        {
            i2c_sda_low();
        }
        i2c_delay();

        i2c_scl_high();
        i2c_delay();
        i2c_scl_low();

        if ( i == 7 )
        {
            i2c_sda_high(); // 释放总线
        }
        data <<= 1;	             // 左移一个bit
        i2c_delay();
    }
}


/**
 *  @brief  i2c 读取一个字节
 *  @param  无
 *  @retval 无
 */
uint8_t i2c_read_byte( void )
{
    uint8_t i;
    uint8_t value;

    /* 读到第1个bit为数据的bit7 */
    value = 0;
    for ( i = 0; i < 8; i++ )
    {
        value <<= 1;
        i2c_scl_high();
        i2c_delay();
        if ( i2c_read_sda_value() != 0 )
        {
            value++;
        }

        i2c_scl_low();
        i2c_delay();
    }

    return value;
}


/**
 *  @brief  CPU等待从设备的应答信号
 *  @param  无
 *  @retval 0表示正确应答，1表示无应答
 */
static uint8_t i2c_wait_ack( void )
{
    uint8_t ret;

    Soft_IIC_Output();

    i2c_sda_high();	/* CPU释放SDA总线 */
    i2c_delay();

    Soft_IIC_Input();
    i2c_scl_high();	/* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
    i2c_delay();
    if ( i2c_read_sda_value() == 1 )	/* CPU读取SDA口线状态 */
    {
        ret = 1;
    }
    else
    {
        ret = 0;
    }

    i2c_scl_low();
    i2c_delay();

    return ret;
}



/**
 *  @brief  CPU产生一个ACK信号
 *  @param  无
 *  @retval 无
 */
static void i2c_ack( void )
{
    Soft_IIC_Output();

    i2c_scl_low();
    i2c_sda_low();	/* CPU驱动SDA = 0 */
    i2c_delay();

    i2c_scl_high();	/* CPU产生1个时钟 */
    i2c_delay();

    i2c_scl_low();
    i2c_delay();

    i2c_sda_high();	/* CPU释放SDA总线 */
}


/**
 *  @brief  CPU产生一个 NACK 信号
 *  @param  无
 *  @retval 无
 */
static void i2c_Nack( void )
{
    Soft_IIC_Output();

    i2c_scl_low();
    i2c_sda_high();	/* CPU驱动SDA = 1 */
    i2c_delay();

    i2c_scl_high();	/* CPU产生1个时钟 */
    i2c_delay();
//
//    i2c_scl_low();
//    i2c_delay();
}


/**
 *  @brief  i2c 发送多个字节
 *  @param  要发送的从机的地址
 *  @param  指向要写入的的数据的指针
 *  @param  要写入的数据的长度
 *  @retval 成功返回0，失败返回-1
 */
int i2c_write_bytes( uint8_t addr, uint8_t *write_buff, uint8_t buff_size )
{
    uint16_t i, j;

    // 1. 发送一个停止信号
    i2c_stop();

    /* 通过检查器件应答的方式，判断内部写操作是否完成, 一般小于 10ms
    CLK频率为200KHz时，查询次数为30次左右
    */
    for ( i = 0; i < 30; i++ )
    {
        // 2. 发起I2C总线启动信号
        i2c_start();

        // 3. 发起控制字节，高7bit是地址，bit0是读写控制位，0表示写，1表示读
        i2c_write_byte( addr );

        // 4. 发送一个时钟，判断器件是否正确应答
        if ( i2c_wait_ack() == 0 )
        {
            break;
        }
    }
    if ( i  == 30 )
    {
        goto cmd_fail;	// 写超时
    }

    for ( i = 0; i < buff_size; ++i )
    {
        for ( j = 0; j < 30; j++ )
        {
            // 5. 发送数据
            i2c_write_byte( write_buff[i] );

            // 6. 等待ACK
            if ( i2c_wait_ack() == 0 )
            {
                break;
            }
        }

        if ( j == 30 )
        {
            goto cmd_fail;	    /* 从器件无应答 */
        }
    }


    // 7. 发送停止信号
    i2c_stop();

    return 0;

cmd_fail:
    i2c_stop();       // 发送写超时
    return -1;
}

/**
 *  @brief  i2c 发送多个字节
 *  @param  要发送的从机的地址
 *  @param  指向要读取的数据的指针
 *  @param  要读取的数据的长度
 *  @retval 成功返回0，失败返回-1
 */
int i2c_read_bytes( uint8_t addr, uint8_t *read_buff, uint8_t buff_size )
{
    uint16_t i;

    for ( i = 0; i < 30; i++ )
    {
        /* 1. 发起I2C总线启动信号 */
        i2c_start();

        /* 2. 读的话，先写入从机地址 */
        i2c_write_byte( addr  );

        /* 3. 发送一个时钟，判断器件是否正确应答 */
        if ( i2c_wait_ack() == 0 )
        {
            break;
        }
    }
    if ( i  == 30 )
    {
        goto cmd_fail;	// 写超时
    }


    for ( i = 0; i < 30; i++ )
    {
        /* 4. 重新启动I2C总线。前面的代码的目的是传送地址，下面开始读取数据 */
        i2c_start();

        /* 5. 发送读控制 */
        i2c_write_byte( addr );

        /* 6. 发送一个时钟，判断器件是否正确应答 */
        if ( i2c_wait_ack() == 0 )
        {
            break;
        }
    }
    if ( i  == 30 )
    {
        goto cmd_fail;	// 写超时
    }


    /* 7. 循环读取数据 */
    for ( i = 0; i < buff_size; i++ )
    {
        read_buff[i] = i2c_read_byte();	/* 读1个字节 */

        /* 每读完1个字节后，需要发送Ack， 最后一个字节不需要Ack，发Nack */
        if ( i != buff_size - 1 )
        {
            i2c_ack();	// 中间字节读完后，CPU产生ACK信号(驱动SDA = 0)
        }
        else
        {
            i2c_Nack();	// 最后1个字节读完后，CPU产生NACK信号(驱动SDA = 1)
        }
    }

    /* 8. 发送I2C总线停止信号 */
    i2c_stop();

    return 0;	/* 执行成功 */

cmd_fail:
    i2c_stop();       // 发送写超时
    return -1;
}

/**
 *  @brief  I2C初始化
 *  @param  无
 *  @retval 无
 */
void i2c_init( void )
{
    i2c_stop();
}

void transfer_data( uint8_t dat )
{
//    start_flag();
//    transfer( 0x7e );
//    transfer( dat );
//    stop_flag();

    uint8_t data;
    uint8_t ret;

    data = dat;

    ret = i2c_write_bytes( 0x7E, &data, 1 );
    if( ret != 0 )
    {
        while( 1 );
    }

}

void transfer_command( uint8_t com )
{
//    start_flag();
//    transfer( 0x7c );
//    transfer( com );
//    stop_flag();

    uint8_t data;
    uint8_t ret;

    data = com;

    ret = i2c_write_bytes( 0x7C, &data, 1 );
    if( ret != 0 )
    {
        while( 1 );
    }
}

void lcd_address( uint8_t page, uint8_t column )
{
    column = column - 1;    //我们平常所说的第1列，在LCD驱动IC里是第0列。所以在这里减去1.
    page = page - 1;
    transfer_command( 0xb0 + page );    //设置页地址。每页是8行。一个画面的64行被分成8个页。我们平常所说的第1页，在LCD驱动IC里是第0页，所以在这里减去1
    transfer_command( ( ( column >> 4 ) & 0x0f ) + 0x10 );	//设置列地址的高4位
    transfer_command( column & 0x0f );  //设置列地址的低4位
}

//全屏清屏
void clear_screen()
{
    unsigned char i, j;
    for( i = 0; i < 8; i++ )
    {
        lcd_address( 1 + i, 1 );
        for( j = 0; j < 192; j++ )
        {
            transfer_data( 0x00 );
        }
    }
}

void display_string_5x8( uint32_t page, uint32_t column, uint8_t reverse, uint8_t *text )
{
    uint8_t i = 0, j, k, data1;
    while( text[i] > 0x00 )
    {
        if( ( text[i] >= 0x20 ) && ( text[i] <= 0x7e ) )
        {
            j = text[i] - 0x20;
            lcd_address( page, column );
            for( k = 0; k < 5; k++ )
            {
                if( reverse == 1 )	data1 = ~ascii_table_5x8[j][k];
                else	data1 = ascii_table_5x8[j][k];
                transfer_data( data1 );
            }
            if( reverse == 1 )	transfer_data( 0xff );
            else	transfer_data( 0x00 );
            i++;
            column += 6;
        }
        else
            i++;
    }
}

void display_graphic_192x64( uint8_t *dp )
{
    uint8_t i, j;
    for( i = 0; i < 8; i++ )
    {
        lcd_address( i + 1, 1 );
        for( j = 0; j < 192; j++ )
        {
            transfer_data( *dp );
            dp++;
        }
    }
}

void initial_lcd( void )
{
    i2c_init();

    //低电平复位
    HAL_GPIO_WritePin( LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET );
    HAL_Delay( 100 );
    HAL_GPIO_WritePin( LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET );
    //复位完毕
    HAL_Delay( 200 );

    transfer_command( 0xe2 );	 //软复位
    HAL_Delay( 200 );
    transfer_command( 0x2f ); //打开内部升压
    HAL_Delay( 200 );
    transfer_command( 0xa0 ); //
    transfer_command( 0x81 ); //微调对比度
    transfer_command( 0x70 ); //微调对比度的值，可设置范围0x00～0xFF
    transfer_command( 0xeb ); //1/9偏压比（bias）
    transfer_command( 0xc4 ); //行列扫描顺序：从上到下
    transfer_command( 0xaf ); //开显示
}




#if 0
//   JLX19264G-901-PN-IIC
//   IIC接口
//   驱动IC是:ST7525


//sbit cs1 = P3 ^ 4;		/*接口定义*/
//sbit reset = P3 ^ 5;	/*接口定义*/
//sbit scl = P1 ^ 0; //对应LCD的SCK(D0)
//sbit sda = P1 ^ 1; //对应LCD的SDA(D1)
//
//sbit key = P2 ^ 0;
//
//#define DataBus P1

//void delay_us( int i );
//void delay( int i );

//void transfer( int data1 )
//{
//    int i;
//    for( i = 0; i < 8; i++ )
//    {
//        scl = 0;
//        if( data1 & 0x80 ) sda = 1;
//        else sda = 0;
//        scl = 1;
//        scl = 0;
//        data1 <<= 1;
//    }
//    sda = 0;
//    scl = 1;
//    scl = 0;
//}
//
//void start_flag()
//{
//    scl = 1;		/*START FLAG*/
//    sda = 1;		/*START FLAG*/
//    sda = 0;		/*START FLAG*/
//}
//
//void stop_flag()
//{
//    scl = 1;		/*STOP FLAG*/
//    sda = 0;		/*STOP FLAG*/
//    sda = 1;		/*STOP FLAG*/
//}

//写命令到液晶显示模块
void transfer_command( uint8_t com )
{
//    start_flag();
//    transfer( 0x7c );
//    transfer( com );
//    stop_flag();

    uint8_t data;
    uint8_t ret;

    data = com;

    ret = HAL_I2C_Master_Transmit( &hi2c1, 0x7C, &data, 1, 1000 );
    if( ret != 0 )
    {
        while( 1 );
    }
}

//写数据到液晶显示模块
void transfer_data( uint8_t dat )
{
//    start_flag();
//    transfer( 0x7e );
//    transfer( dat );
//    stop_flag();

    uint8_t data;
    uint8_t ret;

    data = dat;

    ret = HAL_I2C_Master_Transmit( &hi2c1, 0x7E, &data, 1, 1000 );
    if( ret != 0 )
    {
        while( 1 );
    }

}

////延时1
//void delay( int i )
//{
//    int j, k;
//    for( j = 0; j < i; j++ )
//        for( k = 0; k < 110; k++ );
//}
//
////延时2
//void delay_us( int i )
//{
//    int j, k;
//    for( j = 0; j < i; j++ )
//        for( k = 0; k < 10; k++ );
//}


//LCD模块初始化
void initial_lcd( void )
{
    //低电平复位
    HAL_GPIO_WritePin( LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET );
    HAL_Delay( 100 );
    HAL_GPIO_WritePin( LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET );
    //复位完毕
    HAL_Delay( 200 );

    transfer_command( 0xe2 );	 //软复位
    HAL_Delay( 200 );
    transfer_command( 0x2f ); //打开内部升压
    HAL_Delay( 200 );
    transfer_command( 0xa0 ); //
    transfer_command( 0x81 ); //微调对比度
    transfer_command( 0x70 ); //微调对比度的值，可设置范围0x00～0xFF
    transfer_command( 0xeb ); //1/9偏压比（bias）
    transfer_command( 0xc4 ); //行列扫描顺序：从上到下
    transfer_command( 0xaf ); //开显示
}

void lcd_address( uint8_t page, uint8_t column )
{
    column = column - 1;    //我们平常所说的第1列，在LCD驱动IC里是第0列。所以在这里减去1.
    page = page - 1;
    transfer_command( 0xb0 + page );    //设置页地址。每页是8行。一个画面的64行被分成8个页。我们平常所说的第1页，在LCD驱动IC里是第0页，所以在这里减去1
    transfer_command( ( ( column >> 4 ) & 0x0f ) + 0x10 );	//设置列地址的高4位
    transfer_command( column & 0x0f );  //设置列地址的低4位
}

//全屏清屏
void clear_screen()
{
    unsigned char i, j;
    for( i = 0; i < 8; i++ )
    {
        lcd_address( 1 + i, 1 );
        for( j = 0; j < 192; j++ )
        {
            transfer_data( 0x00 );
        }
    }
}

void display_graphic_192x64( uint8_t *dp )
{
    uint8_t i, j;
    for( i = 0; i < 8; i++ )
    {
        lcd_address( i + 1, 1 );
        for( j = 0; j < 192; j++ )
        {
            transfer_data( *dp );
            dp++;
        }
    }
}

//显示32x32点阵图像、汉字、生僻字或32x32点阵的其他图标
void display_graphic_32x32( uint8_t page, uint8_t column, uint8_t *dp )
{
    uint8_t i, j;
    for( j = 0; j < 4; j++ )
    {
        lcd_address( page + j, column );
        for ( i = 0; i < 32; i++ )
        {
            transfer_data( *dp );		//写数据到LCD,每写完一个8位的数据后列地址自动加1
            dp++;
        }
    }
}

//显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标
void display_graphic_16x16( uint8_t page, uint8_t column, uint8_t *dp )
{
    uint8_t i, j;
    for( j = 0; j < 2; j++ )
    {
        lcd_address( page + j, column );
        for ( i = 0; i < 16; i++ )
        {
            transfer_data( *dp );		//写数据到LCD,每写完一个8位的数据后列地址自动加1
            dp++;
        }
    }
}

//写入一组16x16点阵的汉字字符串（字符串表格中需含有此字）
//括号里的参数：(页，列，汉字字符串）
//void display_string_16x16( uint8_t page, uint8_t column, uint8_t reverse, uint8_t *text )
//{
//    uint8_t i, j, k, data1;
//    uint32_t address;
//    j = 0;
//    while( text[j] != '\0' )
//    {
//        i = 0;
//        address = 1;
//        while( Chinese_text_16x16[i] > 0x7e )
//        {
//            if( Chinese_text_16x16[i] == text[j] )
//            {
//                if( Chinese_text_16x16[i + 1] == text[j + 1] )
//                {
//                    address = i * 16;
//                    break;
//                }
//            }
//            i += 2;
//        }
//        if( column > 191 )
//        {
//            column = 0;
//            page += 2;
//        }
//        if( address != 1 )
//        {
//            for( k = 0; k < 2; k++ )
//            {
//                lcd_address( page + k, column );
//                for( i = 0; i < 16; i++ )
//                {
//                    if( reverse == 1 ) data1 = ~Chinese_code_16x16[address];
//                    else data1 = Chinese_code_16x16[address];
//                    transfer_data( data1 );
//                    address++;
//                }
//            }
//            j += 2;
//        }
//        else
//        {
//            for( k = 0; k < 2; k++ )
//            {
//                lcd_address( page + k, column );
//                for( i = 0; i < 16; i++ )
//                {
//                    if( reverse == 0 ) transfer_data( 0x00 );
//                    else transfer_data( 0xff );
//                }
//            }
//            j++;
//        }
//        column += 16;
//    }
//}

//显示8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标
void display_graphic_8x16( uint8_t page, uint8_t column, uint8_t *dp )
{
    uint8_t i, j;
    for( j = 0; j < 2; j++ )
    {
        lcd_address( page + j, column );
        for ( i = 0; i < 8; i++ )
        {
            transfer_data( *dp );					//写数据到LCD,每写完一个8位的数据后列地址自动加1
            dp++;
        }
    }
}

//显示8x16的点阵的字符串，括号里的参数分别为（页,列，字符串指针）
void display_string_8x16_2( uint8_t page, uint8_t column, uint8_t reverse, uint8_t *text )
{
    uint8_t data1;
    uint32_t i = 0, j, k, n;

    while( text[i] > 0x00 )
    {
        if( ( text[i] >= 0x20 ) && ( text[i] <= 0x7e ) )
        {
            j = text[i] - 0x20;
            for( n = 0; n < 2; n++ )
            {
                lcd_address( page + n, column );
                for( k = 0; k < 8; k++ )
                {
                    if( reverse == 1 ) data1 = ~ascii_table_8x16[j][k + 8 * n];
                    else data1 = ascii_table_8x16[j][k + 8 * n];
                    transfer_data( data1 );
                }
                if( reverse == 0 )	transfer_data( 0x00 );
                else	transfer_data( 0xff );
            }
            i++;
            column += 8;
        }
        else
            i++;

        if( column > 127 )
        {
            column = 0;
            page += 2;
        }
    }
}

void display_string_8x16( uint32_t page, uint32_t column, uint8_t *text )
{
    uint32_t i = 0, j, k, n;
    while( text[i] > 0x00 )
    {
        if( ( text[i] >= 0x20 ) && ( text[i] <= 0x7e ) )
        {
            j = text[i] - 0x20;
            for( n = 0; n < 2; n++ )
            {
                lcd_address( page + n, column );
                for( k = 0; k < 8; k++ )
                {
                    transfer_data( ascii_table_8x16[j][k + 8 * n] ); //显示5x7的ASCII字到LCD上，y为页地址，x为列地址，最后为数据
                }
            }
            i++;
            column += 8;
        }
        else
            i++;
    }
}


//显示一串5x8点阵的字符串
//括号里的参数分别为（页，列，是否反显，数据指针）
void display_string_5x8( uint32_t page, uint32_t column, uint8_t reverse, uint8_t *text )
{
    uint8_t i = 0, j, k, data1;
    while( text[i] > 0x00 )
    {
        if( ( text[i] >= 0x20 ) && ( text[i] <= 0x7e ) )
        {
            j = text[i] - 0x20;
            lcd_address( page, column );
            for( k = 0; k < 5; k++ )
            {
                if( reverse == 1 )	data1 = ~ascii_table_5x8[j][k];
                else	data1 = ascii_table_5x8[j][k];
                transfer_data( data1 );
            }
            if( reverse == 1 )	transfer_data( 0xff );
            else	transfer_data( 0x00 );
            i++;
            column += 6;
        }
        else
            i++;
    }
}

void display_string_5x8_1( uint32_t page, uint32_t column, uint8_t *text )
{
    uint32_t i = 0, j, k;
    while( text[i] > 0x00 )
    {
        if( ( text[i] >= 0x20 ) && ( text[i] < 0x7e ) )
        {
            j = text[i] - 0x20;
            lcd_address( page, column );
            for( k = 0; k < 5; k++ )
            {
                transfer_data( ascii_table_5x8[j][k] ); //显示5x7的ASCII字到LCD上，y为页地址，x为列地址，最后为数据
            }
            i++;
            column += 6;
        }
        else
            i++;
    }
}


#if 0
void main( void )
{
    while( 1 )
    {
        initial_lcd();
        clear_screen();    							//clear all dots
        display_graphic_192x64( bmp2 );
        waitkey();
        clear_screen();    							//clear all dots
        display_graphic_192x64( bmp1 );
        waitkey();
        clear_screen();
        display_string_5x8( 1, 1, 1, "             MENU                " );	//显示5x8点阵的字符串，括号里的参数分别为（页，列，是否反显，数据指针）
        display_string_5x8( 3, 1, 0, "    Select>>>>" );
        display_string_5x8( 3, 100, 1, "1.Graphic      " );
        display_string_5x8( 4, 100, 0, "2.Chinese        " );
        display_string_5x8( 5, 100, 0, "3.Movie          " );
        display_string_5x8( 6, 100, 0, "4.Contrast       " );
        display_string_5x8( 7, 100, 0, "5.Mirror         " );
        display_string_5x8( 8, 1, 1, "    PRE    USER     DEL     NEW     " );
        display_string_5x8( 8, 59, 0, " " );
        display_string_5x8( 8, 94, 0, " " );
        display_string_5x8( 8, 97 + 48, 0, " " );
    }
}
#endif




#endif






